package com.hongsuan.pplive.mobileAPI;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxMenu;
import me.chanjar.weixin.common.bean.WxMenu.WxMenuButton;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;

/**
 * Servlet implementation class WxServlet
 */
public class WxServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected WxMpInMemoryConfigStorage wxMpConfigStorage;
	protected WxMpService wxMpService;
	protected WxMpMessageRouter wxMpMessageRouter;

	@Override
	public void init() throws ServletException {
		super.init();

		wxMpConfigStorage = new WxMpInMemoryConfigStorage();
		wxMpConfigStorage.setAppId("wxb7b0e9ab9289257e"); // 设置微信公众号的appid
		wxMpConfigStorage.setSecret("601abbf38255378f4d1fcdff81ae8465"); // 设置微信公众号的app
																			// corpSecret
		wxMpConfigStorage.setToken("ianhitlgang"); // 设置微信公众号的token
		// config.setAesKey("..."); // 设置微信公众号的EncodingAESKey

		wxMpService = new WxMpServiceImpl();
		wxMpService.setWxMpConfigStorage(wxMpConfigStorage);

		WxMpMessageHandler handler = new WxMpMessageHandler() {
			@Override
			public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
				WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()).build();
				return m;
			}
		};

		// 重构菜单 handle

		WxMpMessageHandler handler_menu = new WxMpMessageHandler() {
			@Override
			public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
				System.out.println("响应 menu 指令********************");
				WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content("菜单已重构").fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()).build();
				buildMenu(); // 重构菜单方法
				return m;
			}
		};

		// 拦截 关联绑定 消息 handle
		WxMpMessageHandler handler_bind = new WxMpMessageHandler() {
			@Override
			public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
				System.out.println("响应 关联绑定 指令********************");
				WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content("请输入身份证号").fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()).build();
				return m;
			}
		};

		// 拦截 身份证号 消息 handle

		WxMpMessageHandler handler_idCardPar = new WxMpMessageHandler() {
			@Override
			public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
				System.out.println("响应 父母身份证号验证 指令********************");
				// 身份证号 初步判断
				String incontent = wxMessage.getContent();
				String backcontent;
				if (incontent.length() != 18) {
					backcontent = "您输入的身份证号位数有误";
				} else {
					backcontent = "请输入电话号码";
				}
				System.out.println("身份证号：" + incontent);
				WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content(backcontent).fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()).build();
				return m;
			}
		};

		// 拦截 电话号码 消息 handle

		WxMpMessageHandler handler_tel = new WxMpMessageHandler() {
			@Override
			public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
				System.out.println("响应 电话号码验证 指令********************");
				// 电话号码 初步判断
				String incontent = wxMessage.getContent();

				/*
				 * String backcontent; if(incontent.length() != 18) {
				 * backcontent = "您输入的电话号位数有误"; }else { backcontent =
				 * "请输入您孩子的身份证号"; }
				 */
				System.out.println("电话号：" + incontent);
				WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content("请以C开头输入您孩子的身份证号").fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()).build();
				return m;
			}
		};

		// 拦截 孩子身份证号 消息 handle

		WxMpMessageHandler handler_idCardChi = new WxMpMessageHandler() {
			@Override
			public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {

				System.out.println("响应 孩子身份证号 指令********************");
				// 电话号码 初步判断
				String incontent = wxMessage.getContent();
				incontent = incontent.substring(1);
				String backcontent;
				if (incontent.length() != 18) {
					backcontent = "您输入的身份证号位数有误";
				} else {
					backcontent = "审核中，请稍后";
				}
				System.out.println("电话号：" + incontent);
				WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content(backcontent).fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()).build();
				return m;
			}
		};

		WxMpMessageHandler handler_wrong = new WxMpMessageHandler() {

			@Override
			public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
				WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content("输入有误").fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()).build();
				return m;
			}
		};

		// 消息路由

		String regex = "\\d{17}[Xx\\d]"; // 父母身份证号 消息匹配
		String regexC = "[cC]\\d{17}[Xx\\d]"; // 孩子身份证号 消息匹配
		String regexTel = "\\d{5,11}";

		wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
		wxMpMessageRouter.rule().async(false).content("哈哈") // 拦截内容为“哈哈”的消息
				.handler(handler).end().rule().async(false).content("关联绑定") // 拦截内容为“关联绑定”的消息
				.handler(handler_bind).next().rule().async(false).rContent(regex) // 拦截内容为
																					// 父母身份证号
																					// 的消息
				.handler(handler_idCardPar).end().rule().async(false).rContent(regexTel) // 拦截内容为
																							// 电话号码
																							// 的消息
				.handler(handler_tel).end().rule().async(false).rContent(regexC) // 拦截内容为
																					// 孩子身份证号
																					// 的消息
				.handler(handler_idCardChi).end().rule().async(false).content("menu") // 拦截内容为“menu”的消息
				.handler(handler_menu).end().rule().msgType(WxConsts.XML_MSG_TEXT).handler(handler_wrong).end();

	}

	// 创建菜单
	private void buildMenu() {
		List<WxMenuButton> x5Meuns = new ArrayList<WxMenuButton>();

		WxMenuButton indexPage = new WxMenuButton();
		indexPage.setName("查询");
		indexPage.setType(WxConsts.BUTTON_VIEW);
		indexPage.setUrl("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + wxMpConfigStorage.getAppId() + "&redirect_uri=http://120.25.195.79/app/index.html&" + "response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect");
		x5Meuns.add(indexPage);

		System.err.println("appid-" + this.wxMpConfigStorage.getAppId());

		WxMenuButton demoPage = new WxMenuButton();
		demoPage.setName("请假");
		demoPage.setType(WxConsts.BUTTON_VIEW);
		demoPage.setUrl("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + wxMpConfigStorage.getAppId() + "&redirect_uri=http://120.25.195.79/app/index.html&" + "response_type=code&scope=snsapi_userinfo&state=2#wechat_redirect");
		x5Meuns.add(demoPage);

		WxMenuButton takeout = new WxMenuButton();
		takeout.setName("绑定");
		takeout.setType(WxConsts.BUTTON_VIEW);
		takeout.setUrl("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + this.wxMpConfigStorage.getAppId() + "&redirect_uri=http://120.25.195.79/app/index.html&" + "response_type=code&scope=snsapi_userinfo&state=3#wechat_redirect");
		x5Meuns.add(takeout);

		WxMenu x5Menu = new WxMenu();
		x5Menu.setButtons(x5Meuns);
		try {
			wxMpService.menuDelete();
			wxMpService.menuCreate(x5Menu);
		} catch (WxErrorException e) {
			e.printStackTrace();
		}
	}

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.setContentType("text/html;charset=utf-8");
		response.setStatus(HttpServletResponse.SC_OK);

		String signature = request.getParameter("signature");
		String nonce = request.getParameter("nonce");
		String timestamp = request.getParameter("timestamp");

		if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
			// 消息签名不正确，说明不是公众平台发过来的消息
			response.getWriter().println("非法请求");
			return;
		}

		String echostr = request.getParameter("echostr");
		if (StringUtils.isNotBlank(echostr)) {
			// 说明是一个仅仅用来验证的请求，回显echostr
			response.getWriter().println(echostr);
			return;
		}

		String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ? "raw" : request.getParameter("encrypt_type");

		if ("raw".equals(encryptType)) {
			// 明文传输的消息
			WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
			WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
			response.getWriter().write(outMessage.toXml());
			return;
		}

		if ("aes".equals(encryptType)) {
			// 是aes加密的消息
			String msgSignature = request.getParameter("msg_signature");
			WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), wxMpConfigStorage, timestamp, nonce, msgSignature);
			WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
			response.getWriter().write(outMessage.toEncryptedXml(wxMpConfigStorage));
			return;
		}

		response.getWriter().println("不可识别的加密类型");
		return;
	}

}
